package com.ruoyi.voucher.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.system.api.RemoteAccountService;
import com.ruoyi.voucher.domain.VoucherTemplateDetail;
import com.ruoyi.voucher.domain.dto.TemplateSummarySubject;
import com.ruoyi.voucher.domain.dto.req.TemplateAddReqDTO;
import com.ruoyi.voucher.domain.dto.req.TemplateDetailReqDTO;
import com.ruoyi.voucher.domain.dto.resp.VoucherTemplateDetailRespDTO;
import com.ruoyi.voucher.domain.dto.req.VoucherTemplateReqDTO;
import com.ruoyi.voucher.domain.dto.resp.VoucherTemplateRespDTO;
import com.ruoyi.voucher.mapper.VoucherTemplateDetailMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import com.ruoyi.voucher.mapper.VoucherTemplateMapper;
import com.ruoyi.voucher.domain.VoucherTemplate;
import com.ruoyi.voucher.service.IVoucherTemplateService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * 凭证模板Service业务层处理
 *
 * @author ruoyi
 * @date 2025-02-21
 */
@Service
@Slf4j
public class VoucherTemplateServiceImpl extends ServiceImpl<VoucherTemplateMapper, VoucherTemplate> implements IVoucherTemplateService {
    @Resource
    private VoucherTemplateMapper voucherTemplateMapper;

    @Resource
    private VoucherTemplateDetailMapper voucherTemplateDetailMapper;

    @Resource
    private RemoteAccountService remoteAccountService;

    @Resource
    private VoucherTemplateDetailServiceImpl templateDetailService;


    /**
     * 查询凭证模板
     *
     * @param id 凭证模板主键
     * @return 凭证模板
     */
    @Override
    public VoucherTemplate selectVoucherTemplateById(Long id) throws Exception {
        VoucherTemplate voucherTemplate = voucherTemplateMapper.selectVoucherTemplateById(id);
        if(voucherTemplate == null){
            throw new Exception("数据有误");
        }
        List<VoucherTemplateDetail> details = voucherTemplateDetailMapper.selectVoucherTemplateDetailByTemplateId(voucherTemplate.getId());
        if (details != null){
            voucherTemplate.setDetails(details);
        }
        return voucherTemplate;
    }

    /**
     * 查询凭证模板列表
     *
     * @param voucherTemplate 凭证模板
     * @return 凭证模板
     */
    @Override
    public List<VoucherTemplate> selectVoucherTemplateList(VoucherTemplate voucherTemplate) {
        return voucherTemplateMapper.selectVoucherTemplateList(voucherTemplate);
    }

    /**
     * 新增凭证模板
     *
     * @param voucherTemplate 凭证模板
     * @return 结果
     */
    @Override
    public int insertVoucherTemplate(VoucherTemplate voucherTemplate) {
        return voucherTemplateMapper.insert(voucherTemplate);
    }

    /**
     * 修改凭证模板
     *
     * @param templateAddReqDTO 凭证模板
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateVoucherTemplate(TemplateAddReqDTO templateAddReqDTO) throws Exception {
        try {
            Long accountId = remoteAccountService.getAccountId();

            // 更新模板主表
            VoucherTemplate template = new VoucherTemplate();
            template.setId(templateAddReqDTO.getId());
            template.setTemplateName(templateAddReqDTO.getTemplateName());
            template.setTypeId(templateAddReqDTO.getTemplateType());
            template.setAccountSetsId(accountId);
            voucherTemplateMapper.updateById(template);

            // 处理明细
            List<TemplateDetailReqDTO> details = templateAddReqDTO.getDetails();
            if (details == null) {
                throw new Exception("借方金额和贷方金额不能同时为空或为0");
            }

            // 删除不再使用的明细
            List<Long> oldDetailIds = templateDetailService.list(
                    new LambdaQueryWrapper<VoucherTemplateDetail>()
                            .eq(VoucherTemplateDetail::getTemplateId, templateAddReqDTO.getId())
            ).stream().map(VoucherTemplateDetail::getId).collect(Collectors.toList());

            List<Long> newDetailIds = details.stream()
                    .map(TemplateDetailReqDTO::getId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());

            oldDetailIds.removeAll(newDetailIds);
            if (!oldDetailIds.isEmpty()) {
                templateDetailService.removeByIds(oldDetailIds);
            }

            // 更新或新增明细
            for (TemplateDetailReqDTO detail : details) {
                VoucherTemplateDetail templateDetail = new VoucherTemplateDetail();
                templateDetail.setTemplateId(templateAddReqDTO.getId());
                templateDetail.setSubjectId(detail.getSubjectId());
                templateDetail.setSummaryId(detail.getSummaryId());
                templateDetail.setDebitAmount(detail.getDebitAmount());
                templateDetail.setCreditAmount(detail.getCreditAmount());

                if (detail.getId() == null) {
                    templateDetailService.save(templateDetail);
                } else {
                    templateDetail.setId(detail.getId());
                    templateDetailService.updateById(templateDetail);
                }
            }
            return 1;
        } catch (Exception e) {
            log.error("修改凭证模版失败", e);
            throw new Exception(e);
        }
    }

    /**
     * 批量删除凭证模板
     *
     * @param ids 需要删除的凭证模板主键
     * @return 结果
     */
    @Override
    public int deleteVoucherTemplateByIds(Long[] ids) {
        return voucherTemplateMapper.deleteVoucherTemplateByIds(ids);
    }

    /**
     * 删除凭证模板信息
     *
     * @param id 凭证模板主键
     * @return 结果
     */
    @Override
    public int deleteVoucherTemplateById(Long id) {
        return voucherTemplateMapper.deleteVoucherTemplateById(id);
    }

    /**
     * @Description: 凭证模版列表
     * @Param: [voucherTemplateReqDto]
     * @return: java.util.List<com.ruoyi.voucher.domain.dto.resp.VoucherTemplateRespDto>
     * @Author: Yuan
     * @Date: 2025/2/26
     */
    @Override
    public List<VoucherTemplateRespDTO> selectTemplateList(VoucherTemplateReqDTO voucherTemplateReqDto) {


        try {
            Long accountId = remoteAccountService.getAccountId();
            voucherTemplateReqDto.setAccountSetsId(accountId);
            System.out.println(voucherTemplateReqDto);
            List<VoucherTemplate> voucherTemplateList = voucherTemplateMapper.getTemplateList(voucherTemplateReqDto);
            if (voucherTemplateList == null || voucherTemplateList.isEmpty()) {
                return new ArrayList<>();
            }
            //对凭证模版id去重
            List<Long> templateIds = voucherTemplateList.stream().map(VoucherTemplate::getId).distinct().collect(Collectors.toList());

            Map<Long, List<VoucherTemplateDetailRespDTO>> detailMap = voucherTemplateDetailMapper.selectDetailsByTemplateIds(templateIds)
                    .stream()
                    .collect(Collectors.groupingBy(VoucherTemplateDetailRespDTO::getDetailId));

            return voucherTemplateList.stream().map(voucherTemplate -> {
                VoucherTemplateRespDTO templateRespDto = new VoucherTemplateRespDTO();
                templateRespDto.setId(voucherTemplate.getId());
                templateRespDto.setTemplateName(voucherTemplate.getTemplateName());
                templateRespDto.setTemplateType(voucherTemplate.getTypeId());

                List<VoucherTemplateDetailRespDTO> details = detailMap.getOrDefault(voucherTemplate.getId(), Collections.emptyList());
                templateRespDto.setDetails(details.stream().map(detail -> {
                    TemplateSummarySubject detailDto = new TemplateSummarySubject();
                    detailDto.setSubjectName(detail.getSubjectName());
                    detailDto.setSummary(detail.getSummary());
                    detailDto.setCreditAmount(detail.getCreditAmount());
                    detailDto.setDebitAmount(detail.getDebitAmount());
                    detailDto.setBalanceDirection(detail.getBalanceDirection());
                    return detailDto;
                }).collect(Collectors.toList()));
                return templateRespDto;
            }).collect(Collectors.toList());
        } catch (Exception e) {
            log.error("获取凭证模块列表失败");
            e.printStackTrace();
            return new ArrayList<>();
        }

    }

    /**
    * @Description: 新增凭证模版
    * @Param: [templateAddReqDTO]
    * @return: int
    * @Author: Yuan
    * @Date: 2025/2/27
    */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addTemplate(TemplateAddReqDTO templateAddReqDTO) throws Exception {
        try {
            Long accountId = remoteAccountService.getAccountId();
            VoucherTemplate template = new VoucherTemplate();
            template.setTemplateName(templateAddReqDTO.getTemplateName());
            template.setTypeId(templateAddReqDTO.getTemplateType());
            template.setAccountSetsId(accountId);
            int templateId = voucherTemplateMapper.insert(template);
            List<TemplateDetailReqDTO> details = templateAddReqDTO.getDetails();
            if (details == null){
                return templateId;
            }
            for (TemplateDetailReqDTO detail : details) {
                VoucherTemplateDetail templateDetail = new VoucherTemplateDetail();
                templateDetail.setTemplateId(template.getId());
                templateDetail.setSubjectId(detail.getSubjectId());
                templateDetail.setSummaryId(detail.getSummaryId());
                templateDetail.setDebitAmount(detail.getDebitAmount());
                templateDetail.setCreditAmount(detail.getCreditAmount());
                voucherTemplateDetailMapper.insert(templateDetail);
            }
            return templateId;
        } catch (Exception e) {
            log.error("新增凭证模版失败");
            throw new Exception(e);
        }
    }
}
